#include <func.h>
#include "client.h"
#include "md5.h"
char *cmd_table[] = {"ls", "cd", "gets", "puts", "pwd", "remove", "mkdir", "rmdir", "tree"};
int recv_msg(int netfd, char *buf);
int send_msg(int netfd, char *buf);

typedef struct shareRes_s
{
    char *cmd;
    char *arg;
    struct sockaddr_in serverAddr;
    char token[2048];
    char user_name[32];
} shareRes_t;

void *threadFunc(void *arg)
{
    printf("thread create sucessfully\n");

    shareRes_t *pshareRes = (shareRes_t *)arg;
    char *pcmd = pshareRes->cmd;
    char *parg = pshareRes->arg;

    int client_fd = socket(AF_INET, SOCK_STREAM, 0);
    int ret = connect(client_fd, (struct sockaddr *)&pshareRes->serverAddr, sizeof(struct sockaddr));
    ERROR_CHECK(ret, -1, "connect");
    send_msg(client_fd, pshareRes->user_name);
    send_msg(client_fd, pshareRes->token);

    if (strcmp(pcmd, "gets") == 0)
    {

        int retnum = 0;
        send_msg(client_fd, arg);
        recv(client_fd, &retnum, sizeof(retnum), 0);
        if (retnum != 0)
        {
            printf("文件名错误:当前目录下没有该文件!\n");
        }
        else
        {
            printf("找到文件!\n");
            getsfile(client_fd, arg);
        }
    } // 下载
    else if (strcmp(pcmd, "puts") == 0)
    {

        char md5_str[33];
        char ret_messge[100] = {0};
        int fd = open(arg, O_RDONLY);
        if (fd == -1)
        {
            printf("文件不存在!\n");
            send_msg(client_fd, "文件不存在!\n");
            // continue;
        }
        else
        {
            send_msg(client_fd, "文件存在!");

            printf("正在计算md5\n");
            Compute_file_md5(fd, md5_str);
            printf("计算完成!\n");
            send_msg(client_fd, md5_str);
            // 发送文件的MD5
            recv_msg(client_fd, ret_messge);
            printf("%s", ret_messge);
            if ((strcmp(ret_messge, "文件已存在!\n")) == 0)
            {
                // continue;
            }
            else
            {
                bzero(ret_messge, sizeof(ret_messge));
                recv_msg(client_fd, ret_messge);
                if ((strcmp(ret_messge, "上传成功!\n")) == 0)
                {
                    printf("%s\n", ret_messge);
                    // continue;
                }
                else
                {
                    sendFile(client_fd, arg);
                }
            }
        }
    }
    else
    {

        printf("The cmd is not 'puts' or 'gets',find the bug please!\n");
        printf("child is going to close netfd= %d and exit!\n", client_fd);
        close(client_fd);
        pthread_exit(NULL);
    }

    pthread_exit(NULL);
}
int is_cmd_legal(char *cmd, char **cmd_table, int len)
{

    int i = 0;
    while (i < len)
    {
        if (strcmp(cmd, cmd_table[i]) == 0)
        {
            return 0;
        }
        i++;
    }

    return -1;
}

// 分割命令
int cmd_separation(char *cmd_string, char *cmd, char *arg)
{
    int len = SIZE(cmd_table);
    char *p = cmd_string;
    int i = 0;
    while ((*p) != ' ' && (*p) != '\n' && (*p) != '\0')
    { // 分离出命令存到cmd
        cmd[i] = *p;
        p++;
        ++i;
    }

    int ret1 = is_cmd_legal(cmd, cmd_table, len);
    if (ret1 == -1)
    {
        return -1;
    }

    if (*p == '\0')
    { // 无参命令
        arg = "\0";
        return 0;
    }

    p++;

    i = 0;
    while (*p != '\0')
    {
        arg[i++] = *p;
        p++;
    }
    return 0;
}

// 接收发出命令后，服务端返回的信息
int recv_msg(int netfd, char *buf)
{
    int length;
    recvn(netfd, &length, sizeof(int));
    recvn(netfd, buf, length);
    return 0;
}

// 向客户端发送命令信息
int send_msg(int netfd, char *buf)
{
    int length;
    length = strlen(buf);
    send(netfd, &length, sizeof(int), 0);
    send(netfd, buf, length, 0);
    return 0;
}

int main(int argc, char *argv[])
{
    ARGS_CHECK(argc, 3);
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(atoi(argv[2]));
    serverAddr.sin_addr.s_addr = inet_addr(argv[1]);
    int ret = connect(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
    ERROR_CHECK(ret, -1, "connect");

    char cmd_string[100] = {0};
    char cmd[10] = {0};
    char arg[100] = {0};
    char cmd_ret_msg[100] = {0};
    char name[20] = {0};
    char password[100] = {0};
    char isserver_connect[10] = {0};

    while (1)
    {
        memset(name, 0, sizeof(name));
        memset(password, 0, sizeof(password));
        printf("请输入用户名:\n");
        scanf("%s", name);
        printf("请输入密码:\n");
        scanf("%s", password);
        int c;
        while ((c = getchar()) != '\n' && c != EOF)
            ;

        send_msg(sockfd, name);
        send_msg(sockfd, password);
        // 传输用户名和密码
        memset(cmd_ret_msg, 0, sizeof(cmd_ret_msg));
        recv_msg(sockfd, cmd_ret_msg);
        printf("%s\n", cmd_ret_msg);
        // 收到返回值

        if (strcmp(cmd_ret_msg, "注册成功") == 0 || strcmp(cmd_ret_msg, "登录成功!") == 0)
        {
            memset(cmd_ret_msg, 0, sizeof(cmd_ret_msg));
            // 清除返回值
            // recv_msg(sockfd,cmd_ret_msg);
            // printf("%s",cmd_ret_msg);
            // memset(cmd_ret_msg,0,sizeof(cmd_ret_msg));
            // recv_msg(sockfd,cmd_ret_msg);
            // printf("%s",cmd_ret_msg);
            break;
        }
    }
    int flag = 0;
    while (1)
    {
        memset(cmd_ret_msg, 0, sizeof(cmd_ret_msg));
        memset(cmd, 0, sizeof(cmd));
        memset(arg, 0, sizeof(arg));
        fgets(cmd_string, 100, stdin);
        cmd_string[strcspn(cmd_string, "\n")] = '\0';

        if (strcmp(cmd_string, "quit") == 0)
        {
            send_msg(sockfd, cmd);
            break;
        }
        int cmd_ret = cmd_separation(cmd_string, cmd, arg);
        /*
           if(flag!=-1)
           {
           memset(isserver_connect,0,sizeof(isserver_connect));
           int exit_ret=recv(sockfd,isserver_connect,sizeof(isserver_connect),0);
           if(exit_ret==0)
           {
           printf("服务器已关闭！\n");
           flag=1;
           }
           }
        */
        if (flag == 1)
        {
            break;
        }
        if (cmd_ret == -1)
        {
            printf("%s命令错误\n", cmd);
            flag = -1;
            continue;
        }
        flag = 0;

        send_msg(sockfd, cmd);
        send_msg(sockfd, arg);

        shareRes_t shareRes;
        bzero(&shareRes, sizeof(shareRes_t));
        shareRes.cmd = cmd;
        shareRes.arg = arg;
        shareRes.serverAddr = serverAddr;
        recv_msg(sockfd, shareRes.user_name);
        recv_msg(sockfd, shareRes.token);

        if (strcmp(cmd, "gets") == 0) // 下载
        {
            int retnum = 0;
            send_msg(sockfd, arg);
            recv(sockfd, &retnum, sizeof(retnum), 0);
            if (retnum == -1)
            {
                printf("文件名错误!\n");
                continue;
            }
            printf("找到文件!\n");
            pthread_t tid;
            pthread_create(&tid, NULL, threadFunc, (void *)&shareRes);
        }
        else if (strcmp(cmd, "puts") == 0)
        {

            pthread_t tid;
            pthread_create(&tid, NULL, threadFunc, (void *)&shareRes);
            char md5_str[33];
            ret = Compute_file_md5(arg, md5_str);
        }
        else
        {
            // 如果不是下载命令就打印返回的信息
            recv_msg(sockfd, cmd_ret_msg);
            printf("%s", cmd_ret_msg);
        }
    }
    close(sockfd);
    return 0;
}
